package com.sz.app.customer.api;

import com.sz.biz.app.web.BaseController;
import com.sz.biz.app.web.security.Des;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.MessagesCodes;
import com.sz.biz.common.customer.entity.CusUser;
import com.sz.biz.common.customer.service.CustomerService;
import com.sz.biz.common.customer.service.CustomerUserService;
import com.sz.biz.common.customer.dto.CusCustomerDto;
import com.sz.biz.common.customer.dto.CusUserBaseInfoDto;
import com.sz.common.base.constants.AppDomain;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.BizException;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.dto.FileInfoDto;
import com.sz.common.core.system.service.SysFileGroupService;
import com.sz.app.customer.api.system.dto.SecurityCenterDto;
import com.sz.app.customer.web.security.SecurityKeys;
import io.swagger.annotations.*;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by xutao on 17/6/2.
 */
@RestController
@RequestMapping("${api}/user/personalaccount")
@Api(description = " ", tags = "004、个人账号")
public class PersonalAccountController extends BaseController {

    @Autowired
    private SecurityKeys securityKeys;

    @Autowired
    CustomerService customerService;

    @Autowired
    CustomerUserService customerUserService;

    @Autowired
    SysFileGroupService fileGroupService;

    /**
     * 基本信息-凭借ID修改子账号信息
     */
    @ApiOperation(value = "基本信息-凭借ID修改账号信息", notes = "基本信息-凭借ID修改子账号信息")
    @RequestMapping(value = "/baseinfo", method = {RequestMethod.PUT})
    public QResultDto updateCusUserById(@RequestBody @Validated CusUserBaseInfoDto cusUserBaseInfoDto) {

        CusUser queryRes = customerUserService.findById(PrincipalUtils.getAccountId());

        CusUser cusUser = new CusUser();

        List<CusUser> cusUserList = new ArrayList<CusUser>();

        BeanUtils.copyProperties(cusUserBaseInfoDto,cusUser);

        cusUser.setId(queryRes.getId());

        cusUser.setRefCustomerId(queryRes.getRefCustomerId());

        if (queryRes != null) {

            List<String> attachments = new ArrayList<String>();

            if (cusUserBaseInfoDto.getUserAvatarID() != null && !"".equals(cusUserBaseInfoDto.getUserAvatarID())) {

                attachments.add(cusUserBaseInfoDto.getUserAvatarID());
            }

            if (StringUtils.isEmpty(attachments) && !StringUtils.isEmpty(queryRes.getUserAvatar())) {

                fileGroupService.removeAllFileFromGroup(queryRes.getUserAvatar());
            }

            if (StringUtils.isEmpty(attachments) && StringUtils.isEmpty(queryRes.getUserAvatar())) {
                //do nothing
            }

            if (!StringUtils.isEmpty(attachments) && !StringUtils.isEmpty(queryRes.getUserAvatar())) {
                String fileGroupId = fileGroupService.saveFileToGroup(queryRes.getUserAvatar(), attachments,
                        "biz.customer.model", "客户" + queryRes.getId() + "账号头像", AppDomain.OPERATION);
                cusUser.setUserAvatar(fileGroupId);
            }

            if (!StringUtils.isEmpty(attachments) && StringUtils.isEmpty(queryRes.getUserAvatar())) {
                String fileGroupId = fileGroupService.createFileGroup(attachments,
                        "biz.customer.model", "客户" + queryRes.getId() + "账号头像", AppDomain.OPERATION);
                cusUser.setUserAvatar(fileGroupId);
            }
        }

        cusUserList.add(cusUser);

        customerUserService.updateCustomer(cusUserList);

        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(cusUser.getId());

        return qResultDto;
    }

    /**
     * 基本信息-凭借子账号Id查询子账号信息
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "基本信息-凭借子账号Id查询子账号信息", notes = "基本信息-凭借子账号Id查询子账号信息")
    @RequestMapping(value = "/baseinfo", method = {RequestMethod.GET})
    public QResultDto findBaseInfoById() throws Exception {

        CusUser cusUser = customerUserService.findById(PrincipalUtils.getAccountId());

        CusUserBaseInfoDto cusUserBaseInfoDto = new CusUserBaseInfoDto();

        BeanUtils.copyProperties(cusUser, cusUserBaseInfoDto);

        List<FileInfoDto> attachments = fileGroupService.getFileDtosByGroupId(cusUser.getUserAvatar());

        if (attachments != null && attachments.size() > 0) {

            cusUserBaseInfoDto.setUserAvatar(attachments.get(0).getPath());
        }

        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(cusUserBaseInfoDto);

        return qResultDto;
    }

    /**
     * 安全中心-更改客户账号密码
     */
    @ApiOperation(value = "安全中心-更改客户账号密码", notes = "安全中心-更改客户账号密码")
    @RequestMapping(value = "/securitycenter/updatepassword", method = {RequestMethod.PUT})
    public ResultDto changePassword(@RequestBody SecurityCenterDto securityCenterDto) throws Exception {

        QResultDto qResultDto = new QResultDto();
        if (!securityCenterDto.getNewPassword().equals(securityCenterDto.getRepeateNewPassword()) ) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CUSTOMER_USER_PASSWORD_NOT_MATCH);
        }
        customerUserService.changeCustomerPassword(PrincipalUtils.getAccountId(), decPassword(securityCenterDto.getOldPassword()),
                decPassword(securityCenterDto.getNewPassword()));
        qResultDto.setMsg("修改密码成功！");
        return qResultDto;
    }

    /**
     * 子账号管理-查询子账号
     *
     * @throws BizException ex
     */
    @ApiOperation(value = "子账号管理-查询子账号", notes = "子账号管理-查询子账号，支持分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sortName", value = "查询的关键字",
                    dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "isAsc", value = "排序类型,true为升序，false为降序", required = false,
                    dataType = "boolean", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query")})
    @RequestMapping(value = "/accountmanagement/search", method = {RequestMethod.GET})
    public QResultDto getUser(@RequestParam(defaultValue = "") String q,
                              @RequestParam(defaultValue = "userName") String sortName,
                              @RequestParam(required = false, defaultValue = "true") boolean isAsc,
                              @RequestParam(defaultValue = "1") int pageIndex,
                              @RequestParam(name = "pageSize", defaultValue = "10") int pageSize) throws BizException {

        q = StringUtils.replaceSqlPattern(q);

        int refCustomerId = 0;

        CusUser cusUser = customerUserService.findById(PrincipalUtils.getAccountId());

        if (cusUser != null) {

            refCustomerId = cusUser.getRefCustomerId();
        }

        return customerUserService.findSimpleCustomerList(q, pageIndex, pageSize, sortName, isAsc, null, refCustomerId);
    }

    /**
     * 子账号管理-新建一个用户账号
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-新建客户账号", notes = "子账号管理-新建客户账号")
    @RequestMapping(value = "/accountmanagement", method = {RequestMethod.POST})
    public ResultDto saveUser(@RequestBody @Validated CusUser cusUser) throws Exception {

        int userId = 0;

        CusUser tempUser = customerUserService.findById(PrincipalUtils.getAccountId());

        if (tempUser != null) {

            cusUser.setRefCustomerId(tempUser.getRefCustomerId());

            userId = customerUserService.save(cusUser);
        }

        ResultDto dto = getOperateSuccessDto(MessagesCodes.MODULE_CUSTOMER_ADD_SUBACCOUNT_SUCCESS);

        dto.setData(userId);

        return dto;
    }

    /**
     * 子账号管理-修改账号
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-修改账号", notes = "子账号管理-修改账号")
    @RequestMapping(value = "/accountmanagement", method = {RequestMethod.PUT})
    public ResultDto updateUser(@RequestBody @Validated CusUser cusUser) throws Exception {

        List<CusUser> cusUserList = new ArrayList<CusUser>();

        CusUser tempUser = customerUserService.findById(PrincipalUtils.getAccountId());

        if (tempUser != null) {

            cusUser.setRefCustomerId(tempUser.getRefCustomerId());

            cusUserList.add(cusUser);

            customerUserService.updateCustomer(cusUserList);
        }

        ResultDto dto = getUpdateSuccessDto(MessagesCodes.MODULE_CUSTOMER_SUBACCOUNT);

        dto.setData(cusUser.getId());

        return dto;
    }

    /**
     * 子账号管理-批量删除客户账号
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-批量删除客户账号", notes = "子账号管理-批量删除客户账号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "客户账号的ids",
                    required = true, dataType = "string", paramType = "body")})
    @RequestMapping(value = "/accountmanagement/deletions", method = {RequestMethod.POST})
    public ResultDto deleteUser(@RequestBody List<Integer> ids) throws Exception {

        customerUserService.batchDelete(ids);

        return getDeleteSuccessDto(MessagesCodes.MODULE_CUSTOMER_SUBACCOUNT);
    }

    /**
     * 子账号管理-锁定客户账号
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-锁定客户账号", notes = "子账号管理-锁定客户账号")
    @RequestMapping(value = "/accountmanagement/lock", method = {RequestMethod.POST})
    public ResultDto lockUser(@ApiParam(value = "客户账号的ids", required = true) @RequestBody List<Integer> ids)
            throws Exception {

        customerUserService.lockCustomer(ids);

        ResultDto dto = getOperateSuccessDto(MessagesCodes.CUSTOMER_LOCK_SUCCESS);

        dto.setData(ids);

        return dto;
    }

    /**
     * 子账号管理-解锁客户账号
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-解锁客户账号", notes = "子账号管理-解锁客户账号")
    @RequestMapping(value = "/accountmanagement/unlock", method = {RequestMethod.POST})
    public ResultDto unLockUser(@RequestBody List<Integer> ids) throws Exception {

        customerUserService.unlockCustomer(ids);

        ResultDto dto = getOperateSuccessDto(MessagesCodes.CUSTOMER_UNLOCK_SUCCESS);

        dto.setData(ids);

        return dto;
    }

    /**
     * 子账号管理-异步校验邮箱
     */
    @ApiOperation(value = "子账号管理-异步校验邮箱", notes = "子账号管理-异步校验邮箱")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "email", value = "邮箱",
                    required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "账号id 修改时传id 新增时传空",
                    dataType = "int", paramType = "query")})
    @RequestMapping(value = "/accountmanagement/checkemail", method = {RequestMethod.GET})
    public ResultDto userEmailCheck(@RequestParam String email,
                                    @RequestParam(required = false, defaultValue = "0") int userId) {
        if (userId == 0) {
            userId = PrincipalUtils.getAccountId();
        }
        customerUserService.customerEmailCheck(userId, email);

        return new ResultDto();
    }

    /**
     * 子账号管理-异步校验用户名称
     */
    @ApiOperation(value = "子账号管理-异步校验用户名称", notes = "子账号管理-异步校验用户名称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名称",
                    required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "账号id 修改时传id 新增时传空",
                    dataType = "int", paramType = "query")})
    @RequestMapping(value = "/accountmanagement/checkusername", method = {RequestMethod.GET})
    public ResultDto userUserNameCheck(@RequestParam String userName,
                                       @RequestParam(required = false, defaultValue = "0") int userId) {

        customerUserService.customerUserNameCheck(userId, userName);

        return new ResultDto();
    }

    /**
     * 子账号管理-异步校验手机号码
     */
    @ApiOperation(value = "子账号管理-异步校验手机号码", notes = "子账号管理-异步校验手机号码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobilePhone", value = "手机号码",
                    required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "账号id 修改时传id 新增时传空",
                    dataType = "int", paramType = "query")})
    @RequestMapping(value = "/accountmanagement/checkmobilephone", method = {RequestMethod.GET})
    public ResultDto checkMobilePhoneExist(@RequestParam String mobilePhone,
                                            @RequestParam(required = false, defaultValue = "0") int userId) {

        boolean exist = customerUserService.checkMobilePhoneExist(userId,mobilePhone);
        ResultDto result = new ResultDto(exist);
        return result;
    }

    /**
     * 子账号管理-凭借主账号Id查询子账号信息
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-凭借主账号Id查询子账号信息", notes = "子账号管理-凭借主账号Id查询子账号信息")
    @RequestMapping(value = "/accountmanagement/findbycustomer/{costomerid}", method = {RequestMethod.GET})
    public QResultDto findUserByCustomerId(@PathVariable int costomerid) throws Exception {

        List<CusUser> cusUserList = customerUserService.findByCustomerId(costomerid);

        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(cusUserList);

        return qResultDto;
    }

    /**
     * 子账号管理-凭借子账号Id查询子账号信息
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "子账号管理-凭借子账号Id查询子账号信息", notes = "子账号管理-凭借子账号Id查询子账号信息")
    @RequestMapping(value = "/accountmanagement/{id}", method = {RequestMethod.GET})
    public QResultDto findUserById(@PathVariable int id) throws Exception {

        CusUser cusUser = customerUserService.findById(id);

        QResultDto qResultDto = new QResultDto();

        qResultDto.setData(cusUser);

        return qResultDto;
    }

    /**
     * 重置客户账号密码
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "重置客户账号密码", notes = "重置客户账号密码")
    @RequestMapping(value = "/resetpasswd", method = {RequestMethod.POST})
    public ResultDto resetpasswd(
            @ApiParam(value = "账号ids", required = true) @RequestBody List<Integer> userids) throws Exception {

        customerUserService.resetUsersPasswd(userids);

        ResultDto dto = getOperateSuccessDto(MessagesCodes.USER_RESET_PASSWORD_SUCCESS);

        dto.setData(userids);

        return dto;
    }

    /**
     * 获取登录客户主账户相关信息
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "获取登录客户主账户相关信息", notes = "获取登录客户主账户相关信息")
    @RequestMapping(value = "/accountmanagement/accountinfo", method = {RequestMethod.GET})
    public ResultDto getMainAccountInfoForLogin() throws Exception {

        Map<String,Object> map = new HashedMap();

        CusUser cusUser = customerUserService.findById(PrincipalUtils.getAccountId());

        if (cusUser != null) {

            CusCustomerDto cusCustomerDto = customerService.findById(cusUser.getRefCustomerId());

            map.put("currencyCode", cusCustomerDto.getTradingCurrency());
            map.put("currencyName", cusCustomerDto.getCurrencyName());

        }

        ResultDto dto = new ResultDto();

        dto.setData(map);

        return dto;
    }

    /**
     * 获取登录客户子账号信息(如果为主账号则返回其下的所有子账号，如果为子账号则直接返回空)
     *
     * @throws Exception ex
     */
    @ApiOperation(value = "获取登录客户子账号信息", notes = "获取登录客户子账号信息(如果为主账号则返回其下的所有子账号，如果为子账号则直接返回空)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query")})
    @RequestMapping(value = "/accountmanagement/subaccountinfo", method = {RequestMethod.GET})
    public QResultDto getSubAccountInfoForLogin(@RequestParam(defaultValue = "") String q,
                                               @RequestParam(defaultValue = "1") int pageIndex,
                                               @RequestParam(name = "pageSize", defaultValue = "10") int pageSize) throws Exception {
        QResultDto qResultDto = null;
        q = StringUtils.replaceSqlPattern(q);
        CusUser cusUser = customerUserService.findById(PrincipalUtils.getAccountId());
        if (cusUser != null) {
            if (cusUser.getIsSystem()) {
                qResultDto = customerUserService.findSubAccountByLoginId(cusUser.getRefCustomerId(),q,pageIndex,pageSize);
            }
        }
        return qResultDto;
    }

    private String decPassword(String password){
        if (org.apache.commons.lang3.StringUtils.isNotBlank(password)) {
            return Des.getDesTool().strDec(password, securityKeys.getSecurityKey1(), securityKeys.getSecurityKey2(), securityKeys.getSecurityKey3());
        }
        return password;
    }
}
